home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Applications
/
Communication
/
NewsBase
/
Source
/
INewsgroupInfoD.m
< prev
next >
Wrap
Text File
|
1993-01-12
|
9KB
|
342 lines
/* Generated by Interface Builder */
#import "INewsgroupInfoD.h"
#import "IZIntPair.h"
#import "data_types.h"
#import "errdebug.h"
#import <objc/List.h>
#import <appkit/Panel.h>
#import <stdio.h>
#import <string.h>
#import <objc/zone.h>
#import "Localization.h"
#define LoStr(key) doLocalString(NULL,key,NULL)
@implementation INewsgroupInfoD
- initWithKey:(const char *)dataKey
{
iPairList = [[List allocFromZone:[self zone]] init];
[super initWithKey:dataKey];
return self;
}
- (BOOL)checkArticleIsRead:(int)kartnum
{
int ti;
IZIntPair *intPair;
[self _readArticleNumSet]; /* set art_num_set to ipair_a_num[] */
/* if it's already read : return YES */
/* not read: return NO */
for (ti=0; intPair=[iPairList objectAt:ti]; ++ti) {
if (([intPair first] <= kartnum) && (kartnum <= [intPair last]))
return YES;
}
return NO;
}
- (void)markReadArticle:(int)kartnum;
{
int i;
IZIntPair *intPair, *lastIntPair, *rightPair, *newPair;
int maxIndex;
[self _readArticleNumSet];
if ([self checkArticleIsRead:kartnum]) /*set art_num_set to ipair_a_num */
return; /*if already marked, return */
/* handle last object */
lastIntPair = [iPairList lastObject];
if (([iPairList count]==0) || ([lastIntPair last] < kartnum)){
if (([lastIntPair last] +1) == kartnum ) {
/* xxx-xxx type */
[lastIntPair setLast:kartnum];
} else {
/* xxx-xxx,xxx type */
newPair = [[IZIntPair allocFromZone:[self zone]] init];
[newPair setFirst:kartnum last:kartnum];
[iPairList addObject:newPair];
}
[self _writeArticleNumSet];
return;
}
maxIndex = [iPairList count] - 1;
for (i=(maxIndex-1); i>=0; i--) {
intPair = [iPairList objectAt:i];
rightPair = [iPairList objectAt:(i+1)];
if (([intPair last] < kartnum) && (kartnum < [rightPair first])) {
if (([intPair last]+1 == kartnum)
&& ( kartnum+1 == [rightPair first])) {
/* 0-219,210,211-220 -> 0-220 type */
[intPair setLast:[rightPair last]];
/* remove rightPair */
[iPairList removeObjectAt:(i+1)];
[rightPair free];
} else if (([intPair last]+1) == kartnum) {
/* 0-120,121,210-220 -> 0-121,210-220 type */
[intPair setLast:kartnum];
} else if ((kartnum+1) == [rightPair first]) {
/* 0-120,219,210-220 -> 0-120,219-220 type */
[rightPair setFirst:kartnum];
} else {
/* 0-120,150,210-220 type */
/* insert object */
newPair = [[IZIntPair allocFromZone:[self zone]] init];
[iPairList insertObject:newPair at:(i+1)];
[newPair setFirst:kartnum last:kartnum];
}
}
}
/* put read-article data to groupInfo */
[self _writeArticleNumSet];
return;
}
- (BOOL)isAllArticleMarked
{
int first, last;
int i;
first = (int)[self infoForKey:FIRST];
last = (int)[self infoForKey:LAST];
for (i=first; i<=last; ++i) {
if ([self checkArticleIsRead:i]==NO) {
return NO;
}
}
return YES;
}
- (int)countArticleUnMarked
{
int first, last;
int i;
int art_count;
first = (int)[self infoForKey:FIRST];
last = (int)[self infoForKey:LAST];
art_count = 0;
for (i=first; i<=last; ++i) {
if ([self checkArticleIsRead:i]==NO) {
++art_count;
}
}
return art_count;
}
- (void)unmarkReadArticle:(int)kartnum
{
int i;
IZIntPair *intPair, *newPair;
[self _readArticleNumSet]; /*set art_num_set to ipair_a_num */
if (!([self checkArticleIsRead:kartnum]))
return; /*if not marked, return */
for (i=0; intPair=[iPairList objectAt:i]; i++) {
/* xxx */
if (kartnum==[intPair first] && kartnum==[intPair last]) {
/* remove xxx */
if ([intPair first] == kartnum) {
/* copy, 123-150,176,180-210 -> 123-150,180-210 */
[iPairList removeObjectAt:i];
[intPair free];
break;
}
/* xxx-xxx */
} else if ([intPair first] == kartnum) {
/* 123-150 -> 124-150 */
[intPair setFirst:([intPair first]+1)];
break;
} else if ([intPair last] == kartnum) {
/* 123-150 -> 123-149 */
[intPair setLast:([intPair last]-1)];
break;
} else if (([intPair first] < kartnum) && (kartnum < [intPair last])) {
/* 123-150 -> 123-135,137-150 */
/* copy */
newPair = [[IZIntPair allocFromZone:[self zone]] init];
[iPairList insertObject:newPair at:(i+1)];
[newPair setFirst:(kartnum+1) last:[intPair last]];
[intPair setLast:(kartnum-1)];
break;
}
}
/* put read-article data to groupInfo */
[self _writeArticleNumSet];
return;
}
- (void)markAllArticle
{
IZIntPair *intPair;
[iPairList freeObjects];
intPair = [[IZIntPair allocFromZone:[self zone]] init];
[iPairList addObject:intPair];
[intPair setFirst:0 last:(int)[self infoForKey:LAST]];
[self _writeArticleNumSet];
return;
}
- (void)_readArticleNumSet
{
char *art_num_set, ch;
int first, last;
int num_read;
IZIntPair *intPair;
if ([iPairList count] > 0) {
return;
}
art_num_set = (char *)[self infoForKey:ART_NUM_SET];
/* store data to instance val. */
ch=' ';
while ((num_read = sscanf(art_num_set,"%d-%d", &first, &last))
&& ch !='\0') {
intPair = [[IZIntPair allocFromZone:[self zone]] init];
[iPairList addObject:intPair];
if (num_read == 2) { /* xxx-xxx type */
[intPair setFirst:first last:last];
} else { /* xxx type */
[intPair setFirst:first last:first];
} /* descripter is '.' or ' ' */
/* and go to next descripter */
/* skip the pointer(art_num_set) to the head of next set */
// while(!((ch = *(art_num_set++)) == ',' || ch == ' ' || ch =='\0'))
while(!((ch = *(art_num_set++)) == ',' || ch =='\0'))
;
}
if ([iPairList count] == 0) {
intPair = [[IZIntPair allocFromZone:[self zone]] init];
[iPairList addObject:intPair];
[intPair setFirst:(int)0 last:(int)0];
}
return;
}
- (void)_writeArticleNumSet
{
#define LINE_MAX_LEN 4088
int i;
char line_buf[LINE_MAX_LEN], *line_buf_ptr;
IZIntPair *intPair;
/* print art num. set */
line_buf[0] = '\0';
line_buf_ptr = line_buf;
for (i=0; intPair=[iPairList objectAt:i]; ++i) {
if (strlen(line_buf) > (LINE_MAX_LEN - 24)) {
/* 4 byte integer needs 10 chars, so 20. and '-'','' ''\0' */
NXRunAlertPanel(LoStr("NewsBase"),
LoStr("newsrc file: length of line over flow"),
LoStr("OK"),NULL,NULL);
return;
}
/* move pointer to string's end */
line_buf_ptr = strchr(line_buf, '\0');
if ([intPair first] < [intPair last]) {
/* ..., xxx-xxx */
sprintf(line_buf_ptr, "%d-%d",
(int)[intPair first], (int)[intPair last]);
} else {
/* ..., xxx */
sprintf(line_buf_ptr, "%d", (int)[intPair first]);
}
/* move pointer to string's end */
line_buf_ptr = strchr(line_buf, '\0');
if (i != ([iPairList count]-1)) {
/* add ',' */
sprintf (line_buf_ptr, ",");
}
}
DBG(1,fprintf (stderr," art_num_set = %s\n", line_buf));
[self addInfoString:line_buf key:ART_NUM_SET];
}
- (int)firstArticleForAmount:(int)artWillGetNum
{
int amount;
int last;
int i;
if (artWillGetNum==0) {
return 0;
}
last = (int)[self infoForKey:LAST];
amount = [self countArticleUnMarked];
i = last + 1;
while ((artWillGetNum > 0) && (amount > 0) && (--i > 0)) {
if ([self checkArticleIsRead:i]==NO) {
/* article is unmarked one */
--artWillGetNum;
--amount;
}
}
return i;
}
- addInfoInt:(int)theValue key:(char *)theKey;
{
unsigned int i, ti;
int first, last, ex_last;
IZIntPair *intPair;
if (strcmp(theKey,FIRST) == 0) {
/* key is FIRST, try to clean up ART_NUM_SET */
if ([self infoForKey:ART_NUM_SET] != nil) {
/* this groupinfo has ART_NUM_SET, iPairList is set */
for (i=[iPairList count]-1;
((intPair=[iPairList objectAt:i])!=nil && i!=0); i--) {
first = [intPair first];
last = [intPair last];
ex_last = theValue - 1;
/* if there is "1, ... xxx-yyy .... theValue", */
/* remove article # set under theValue(i.e. xxx-yyy) */
/* i.e. remove "1-ex_last" */
if (ex_last < (first-1)) {
/* theValue ... xxx-yyy */
continue;
}
if ((first-1) <= ex_last && ex_last <= last) {
/* theValue is 124, so 0-123 is already read */
/* 0, ..., 123-130 -> 0-130, ... */
/* or, 0, ...., 120-130 -> 0-130 */
/* or, 0, ...., 120-123 -> 0-123 */
for (ti=i; ti>=1; --ti) {
[iPairList removeObjectAt:ti];
}
[[iPairList objectAt:0] setFirst:0 last:last];
break;
} else if (last < ex_last) {
/* 0, ...., xxx-120, 130-135 -> 0-123, 130-135,...*/
for (ti=i; ti>=1; --ti) {
[iPairList removeObjectAt:ti];
}
[[iPairList objectAt:0] setFirst:0 last:ex_last];
break;
}
}
}
}
return [super addInfoInt:theValue key:theKey];
}
@end